class OrarioIllegale <Exception
end

class TrenoIllegale <Exception
end

class Orario

  attr_reader :ore, :minu
  include Comparable
  
 def initialize(ore,minu)
   if ore>=0 && ore<=23 && minu>=0 && minu<=59
   @ore = ore
   @minu = minu
   else
     raise OrarioIllegale
  end
 end

 def to_s
   if minu>=10
     "#{@ore}:#{@minu}"
   else
     "#{@ore}:0#{@minu}"
   end
 end

 def <=>(b)
   return @ore <=> b.ore if @ore != b.ore
   return @minu <=> b.minu
 end

end

class Ferrovia
    

  def initialize()
    @treno=[]
    @fermate={}
    @orari={}
  end

  def aggiungi_treno(nome_treno,lista_fermate,lista_orari)
    if lista_fermate.size!=lista_orari.size || lista_orari.sort != lista_orari
      raise TrenoIllegale
    else
   @treno << nome_treno
   @fermate[nome_treno] = lista_fermate
   @orari[nome_treno] = lista_orari
  end
  end

  def stampa_partenze(stazione)
    temp={}
    qqq=[]
    for i in @treno
      for x in 0..@fermate[i].size-2
        if @fermate[i][x]==stazione
           temp[i]=@orari[i][x]
        end
    end
    end
    #temp.each_key{|a| puts "#{temp[a]}\n"}
    qqq=temp.sort {|a,b| a[1]<=>b[1]}
    qqq.each{|w| puts "#{w[0]}  #{w[1]}"}

  end

  def treni_da_a(s1,s2)
    ris=[]
      for i in @treno
       for x in 0..@fermate[i].size-2
        if @fermate[i][x]==s1 
            for w in x..@fermate[i].size-1
              if @fermate[i][w]==s2
          ris << i
        end
       end
      end
       end
      end
    return ris
  end

def cerca_treno_diretto(s1, s2, o1)
  diretti=[]
  @treno.each{|x|
  if nil!=(q=@fermate[x].index(s1)) && nil!=(w=@fermate[x].index(s2)) && q<w && @orari[x][q]>o1
    diretti << [x,@orari[x][w]]
  end
  }
 
if diretti.empty?
  return []
else
  return diretti.min{|a,b| a.last<=>b.last}
end
end



def cerca_treno_1cambio(s1,s2,o1)
  l=[]
for i in @treno
  for x in 0..@fermate[i].size-2
    if @fermate[i][x]==s1 && @orari[i][x]>o1
      for j in x..@fermate[i].size-1
        ris=cerca_treno_diretto(@fermate[i][j],s2,@orari[i][j])
        if ris!=[]
          l<<[i]+ris
        end
      end
      
    end
  end
end
if l.empty?
  return []
else
  return l.min{|x,y| x.last<=>y.last}
end

end


end





def main()

  f = Ferrovia.new()

  puts "--------- Inserimento treni ----------"

  # ------ treni illegali
  begin
    f.aggiungi_treno("MiTo1", ["Torino", "Milano"],
      [Orario.new(9,01),Orario.new(9,30),Orario.new(10,00)])
  rescue TrenoIllegale => e
    puts "Il treno #{e} non e' corretto"
  end

  begin
    f.aggiungi_treno("MiTo2", ["Torino", "Novara", "Milano"],
      [Orario.new(9,01),Orario.new(9,59),Orario.new(9,58)])
  rescue TrenoIllegale => e
    puts "Il treno #{e} non e' corretto"
  end

  # ------------- TO->RM  -------------
  f.aggiungi_treno("Arlecchino",
    ["Torino", "Asti","Alessandria","Genova" ,"Pisa","Roma"],
    [Orario.new(9,00),Orario.new(9,20),Orario.new(10,10),
     Orario.new(11,05),Orario.new(12,20),Orario.new(15,30)])

  f.aggiungi_treno("Balanzone",
    ["Torino", "Asti","Alessandria","Genova" ,"Pisa","Roma"],
    [Orario.new(11,00),Orario.new(11,20),Orario.new(12,10),
     Orario.new(13,05),Orario.new(14,20),Orario.new(17,30)])

  f.aggiungi_treno("Brighella",
    ["Torino", "Asti","Alessandria","Genova" ,"Pisa","Roma"],
    [Orario.new(13,00),Orario.new(13,20),Orario.new(14,10),
     Orario.new(15,05),Orario.new(16,20),Orario.new(19,30)])

  f.aggiungi_treno("Pulcinella",
    ["Torino", "Asti","Alessandria","Genova" ,"Pisa","Roma","Napoli"],
    [Orario.new(15,00),Orario.new(15,20),Orario.new(16,10),
     Orario.new(17,05),Orario.new(18,20),Orario.new(21,30),Orario.new(23,50)])

  f.aggiungi_treno("Pendolino",
    ["Torino", "Roma"],
    [Orario.new(11,30),Orario.new(13,10)])

  f.aggiungi_treno("Andrea Doria",
    ["Genova", "Roma"],
    [Orario.new(14,10),Orario.new(17,15)])


  # ------------- RM->TO  -------------
  f.aggiungi_treno("Cavour",
    ["Roma","Livorno","Pisa","Genova","Alessandria","Asti","Torino"],
    [Orario.new(9,10),Orario.new(11,55),Orario.new(12,10),Orario.new(14,10),
     Orario.new(15,10),Orario.new(15,50),Orario.new(16,10)])

  f.aggiungi_treno("Rattazzi",
    ["Roma","Livorno","Pisa","Genova","Alessandria","Asti","Torino","Aosta"],
    [Orario.new(11,10),Orario.new(13,55),Orario.new(14,10),Orario.new(16,10),
     Orario.new(17,10),Orario.new(17,50),Orario.new(18,10),Orario.new(19,10)])

  f.aggiungi_treno("Regionale117",
    ["Alessandria","Solero","Felizzano","Rocchetta-Tanaro",
     "Asti","Villafranca","Trofarello","Torino"],
    [Orario.new(8,10),Orario.new(8,15),Orario.new(8,20),Orario.new(8,25),
     Orario.new(8,40),Orario.new(8,55),Orario.new(9,10),Orario.new(9,20)])



  # ------------- LI->GE  -------------
  f.aggiungi_treno("Puccini",
    ["Livorno", "Pisa", "La Spezia", "Chiavari", "Rapallo", "Genova"],
    [Orario.new(13,50),Orario.new(14,00),Orario.new(15,10),
     Orario.new(15,40),Orario.new(15,50),Orario.new(16,15)])


  # ----- TO->BO->PE
  f.aggiungi_treno("Tintoretto",
    ["Torino", "Asti","Alessandria","Piacenza" ,"Parma","Modena","Bologna"],
    [Orario.new(14,00),Orario.new(14,20),Orario.new(15,15),
     Orario.new(15,45),Orario.new(16,40),Orario.new(17,30),Orario.new(18,10)])

  f.aggiungi_treno("Caravaggio",
    ["Torino", "Asti","Alessandria","Piacenza","Bologna","Ancona","Pescara"],
    [Orario.new(16,15),Orario.new(16,40),Orario.new(17,15),
     Orario.new(17,45),Orario.new(19,45),Orario.new(21,15),Orario.new(22,00)])

  # ----- TO->VE
  f.aggiungi_treno("Padania",
    ["Torino", "Vercelli","Novara","Milano" ,"Verona","Venezia"],
    [Orario.new(10,00),Orario.new(10,20),Orario.new(11,10),
     Orario.new(12,00),Orario.new(13,10),Orario.new(14,50)])


  # ----- LI->FI
  f.aggiungi_treno("Donatello",
    ["Livorno", "Pisa", "Firenze"],
    [Orario.new(12,10),Orario.new(12,25),Orario.new(13,20)])

  f.aggiungi_treno("Giotto",
    ["Livorno", "Pisa", "Firenze"],
    [Orario.new(14,10),Orario.new(14,25),Orario.new(15,20)])

  # ----- FI->RM
  f.aggiungi_treno("Michelangelo",
    ["Firenze", "Arezzo", "Roma"],
    [Orario.new(16,10),Orario.new(16,50), Orario.new(18,10)])

  # ----- RM->PE
  f.aggiungi_treno("D'Annunzio",
    ["Roma", "Pescara"],
    [Orario.new(17,30),Orario.new(20,45)])


  # --------- da qui iniziano gli esperimenti ----------------

  puts "---------- Inizio test Ferrovia------------"
  puts "--- Partenze da Torino\n"
  f.stampa_partenze("Torino")

  puts "--- Partenze da Alessandria\n"
  f.stampa_partenze("Alessandria")

  puts "--- Treni da Genova a Roma\n"
  puts f.treni_da_a("Genova","Roma")
  #puts "--- Treni da Genova a Roma (con orari partenza/arrivo)\n"
  #f.stampa_treni_da_a("Genova","Roma")

  puts "--- Treni da Livorno a Pisa\n"
  puts f.treni_da_a("Livorno","Pisa")


  puts "--- Miglior treno da Torino a Roma dopo le 9 e 30\n"
  x = f.cerca_treno_diretto("Torino","Roma",Orario.new(9,30))
  if x.size>0
    puts "Treno #{x[0]} con arrivo alle #{x[1]}"
  else
    puts "Nessun treno trovato"
  end

  puts "--- Miglior treno da Vercelli a Milano dopo le 11 e 30\n"
  x = f.cerca_treno_diretto("Vercelli","Milano",Orario.new(11,30))
  if x.size>0
    puts "Treno #{x[0]} con arrivo alle #{x[1]}"
  else
    puts "Nessun treno trovato"
  end


  puts "--- Miglior treno da Asti a Alessandria dopo le 13 e 30\n"
  x = f.cerca_treno_diretto("Asti","Alessandria",Orario.new(13,30))
  if x.size>0
    puts "Treno #{x[0]} con arrivo alle #{x[1]}"
  else
    puts "Nessun treno trovato"
  end


  puts "--- Combinazione da Alessandria a Firenze dopo le 9 con un cambio\n"
   x = f.cerca_treno_1cambio("Alessandria","Firenze",Orario.new(9,0))

  if x.size>0
    puts "Treni #{x[0]} + #{x[1]} con arrivo alle #{x[2]}"
  else
    puts "Nessuna combinazione trovata"
  end

  puts "--- Combinazione da Alessandria a Verona dopo le 7 con un cambio\n"
  x = f.cerca_treno_1cambio("Alessandria","Verona",Orario.new(7,0))
  if x.size>0
    puts "Treni #{x[0]} + #{x[1]} con arrivo alle #{x[2]}"
  else
    puts "Nessuna combinazione trovata"
  end


  puts "--- Combinazione da Genova a Pescara dopo le 14 con un cambio\n"
  x = f.cerca_treno_1cambio("Genova","Pescara",Orario.new(14,0))
  if x.size>0
    puts "Treni #{x[0]} + #{x[1]} con arrivo alle #{x[2]}"
  else
    puts "Nessuna combinazione trovata"
  end


  puts "--- Combinazione da Genova a Pescara dopo le 15 con un cambio\n"
  x = f.cerca_treno_1cambio("Genova","Pescara",Orario.new(15,0))
  if x.size>0
    puts "Treni #{x[0]} + #{x[1]} con arrivo alle #{x[2]}"
  else
    puts "Nessuna combinazione trovata"
  end

  puts "--- Combinazione da Genova a Pescara dopo le 17 con un cambio\n"
  x = f.cerca_treno_1cambio("Genova","Pescara",Orario.new(17,0))
  if x.size>0
    puts "Treni #{x[0]} + #{x[1]} con arrivo alle #{x[2]}"
  else
    puts "Nessuna combinazione trovata"
  end


  puts "----------- Fine test Ferrovia -------------"
end

main()